package com.example.blog.ws;

import com.example.blog.ws.config.GetHttpSessionConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint(value = "/video", configurator = GetHttpSessionConfig.class)
@Slf4j
public class WebSocketServer {

    private static final ConcurrentHashMap<String, WebSocketServer> clientsMap = new ConcurrentHashMap<>();
    private Session session;
    private String userName;

    @OnOpen
    public void open(Session session, EndpointConfig config) {
        userName = (String) config.getUserProperties().get("userName");
        if (userName != null) {
            log.info(userName + " 连接成功");
            clientsMap.put(userName, this);
            this.session = session;
        } else {
            log.info("未知用户尝试连接，但未提供用户名");
        }
    }

    @OnClose
    public void close() {
        if (userName != null) {
            clientsMap.remove(userName);
            log.info(userName + " 断开连接");
        }
    }

    @OnError
    public void error(Throwable error) {
        log.error(userName + " 连接发生错误", error);
    }

    @OnMessage
    public void getMessage(String message) {
        log.info("收到来自 " + userName + " 的消息: " + message);
        clientsMap.forEach((key, value) -> {
            if (!key.equals(this.userName)) {
                try {
                    value.send(message);
                    log.info("消息已转发给 " + key);
                } catch (IOException e) {
                    log.error("向 " + key + " 发送消息失败", e);
                }
            }
        });
    }

    private void send(String message) throws IOException {
        if (session != null && session.isOpen()) {
            session.getBasicRemote().sendText(message);
            log.info("发送消息给 " + userName + ": " + message);
        } else {
            log.info(userName + " 不在线");
        }
    }


    public int getConnectNum() {
        log.info("当前连接数: " + clientsMap.size());
        return clientsMap.size();
    }
}
